package net.teamclerks.rpgf.inventory.item;

import net.teamclerks.rpgf.script.action.ItemAction;
import net.teamclerks.rpgf.script.director.Director;

/**
 * Item is a unique Item in an Inventory. The Count represents
 * the number of this Item in the context of an Inventory. Items
 * can exist out of the context of an Inventory (such as in a chest,
 * or as the loot dropping off a monster, or simply the result of
 * an AcquireItemAction).<br/>
 * <br/>
 * IMPORTANT - By default, all Items have an anonymous ItemAction
 * associated with them at the time of construction which are
 * entirely impotent. Calling <code>doAction</code> against an Item
 * without explicitly setting that Item's ItemAction will do nothing,
 * though the call will succeed.
 * @author msmith
 *
 */
public abstract class Item
{
  /// DATAPOINTS ///
  protected long id;
  protected String name;
  
  /// CONTROL DATA ///
  protected boolean consumable;
  protected boolean usable;
  protected int count;
  protected boolean possessedByPlayer;
  protected int sortOrder;
  protected ItemAction action;
  
  /**
   * Reference to system's Director.
   */
  protected Director director;

  /// DENY CONSTRUCTOR ///
  private Item(){}
  
  /// PUBLIC CONSTRUCTOR ///
  /**
   * Public constructor.
   * @param director
   */
  public Item(Director director)
  {
    this();
    this.director = director;
    // By default all Items have an anonymous ItemAction
    // which does nothing.
    this.action = new ItemAction(director)
    {
      @Override public void act(){}
    };
  }
  
  /// PUBLIC METHODS ///
  /**
   * Gets the Count of this Item in an Inventory.
   * @return count
   */
  public final int getCount()
  {
    return this.count;
  }
  /**
   * Sets the Count of this Item in an Inventory.
   * @param count
   */
  public final void setCount(int count)
  {
    this.count = count;
  }
  /**
   * Gets the ID of this Item.
   * @return id
   */
  public final long getId()
  {
    return id;
  }
  /**
   * Sets the ID of this Item.
   * @param id
   */
  public final void setId(long id)
  {
    this.id = id;
  }
  /**
   * Gets the Name of this Item.
   * @return name
   */
  public final String getName()
  {
    return name;
  }
  /**
   * Sets the Name of this Item in an Inventory.
   * @param name
   */
  public final void setName(String name)
  {
    this.name = name;
  }
  /**
   * Gets whether this Item is consumable.
   * @return consumable
   */
  public final boolean isConsumable()
  {
    return consumable;
  }
  /**
   * Sets whether this Item is consumable.
   * @param consumable
   */
  public final void setConsumable(boolean consumable)
  {
    this.consumable = consumable;
  }
  /**
   * Whether the two items in question are equal.
   * @param item
   * @return
   */
  public final boolean equals(Item item)
  {
    return id == item.getId();
  }
  /**
   * @return the usable
   */
  public final boolean isUsable()
  {
    return usable;
  }
  /**
   * @param usable the usable to set
   */
  public final void setUsable(boolean usable)
  {
    this.usable = usable;
  }
  /**
   * Whether this Item is actually IN the Inventory.<br/>
   * <br/>
   * If an Item is "lost" from the Inventory, it does not
   * get removed from the cache of Items, instead it is simply
   * set such that <code>possessedByPlayer = false</code>. In
   * this way, it is still "in" in the Inventory, but the player
   * cannot see it or interact with it.
   * @return the possessedByPlayer
   */
  public final boolean isPossessedByPlayer()
  {
    return possessedByPlayer;
  }
  /**
   * @param possessedByPlayer the possessedByPlayer to set
   */
  public final void setPossessedByPlayer(boolean possessedByPlayer)
  {
    this.possessedByPlayer = possessedByPlayer;
  }
  /**
   * @return the sortOrder
   */
  public final int getSortOrder()
  {
    return sortOrder;
  }
  /**
   * @param sortOrder the sortOrder to set
   */
  public final void setSortOrder(int sortOrder)
  {
    this.sortOrder = sortOrder;
  }
  /**
   * @return the ItemAction of this Item
   */
  public final ItemAction getItemAction()
  {
    return this.action;
  }
  /**
   * @param itemAction the ItemAction to set
   */
  public final void setItemAction(ItemAction itemAction)
  {
    this.action = itemAction;
  }
}
